// Bins.cpp: implementation of the CBins class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Bins.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBinList::CBinList(int size)
{
	mSize = size;
	mBinList = new Bin[mSize];
	for (int i = 0; i< mSize; i++)
		mBinList[i].Index = i;
	mShortestAvailableBin = 0;
}

CBinList::CBinList(CBinList &binList)
{
	mSize = binList.GetSize();
	mBinList = new Bin[mSize];
	mShortestAvailableBin = 0;
	for (int i=0; i< mSize; i++)
	{
		mBinList[i].CurrentHeight = binList.GetValueAt(i);
		mBinList[i].Index = binList.GetIndexAt(i);
		mBinList[i].StackSize = binList.mBinList[i].StackSize;
		for (int j = 0; j<mBinList[i].StackSize; j++)
			mBinList[i].Stack[j] = binList.mBinList[i].Stack[j];
	}
}

CBinList::~CBinList()
{
	for (int i = 0; i< mSize; i++)
		delete [] (mBinList[i].Stack);
	delete [] mBinList;
}


Bin* CBinList::GetShortestAvailableBin()
{
	if (mShortestAvailableBin > mSize-1)
		return NULL;
	else
		return mBinList + mShortestAvailableBin;
}

bool CBinList::AddHeight(int i, float value)
{
	if ( i>=0 && i < mSize)
	{
		float newValue = mBinList[i].CurrentHeight + value;
		int currentIndex = mBinList[i].Index;
		int currentStackSize = mBinList[i].StackSize;
		float *currentStack = mBinList[i].Stack;
		if (value == 0)
			return true;
		if (value > 0)//New value is bigger than current value, we check the elements after this index i
		{
			if (i == mSize - 1)
				mBinList[i].CurrentHeight = newValue;
			else
			{
				int j = i + 1;
				while (j< mSize && mBinList[j].CurrentHeight < newValue)
				{
					j++;
				}
				//Move the current values that is smaller than new value
				for (int k = i + 1; k < j; k++)
				{
					mBinList[k-1].CurrentHeight = mBinList[k].CurrentHeight;
					mBinList[k-1].Index = mBinList[k].Index;
					mBinList[k-1].StackSize = mBinList[k].StackSize;
					mBinList[k-1].Stack = mBinList[k].Stack;
				}
				mBinList[j-1].CurrentHeight = newValue;
				mBinList[j-1].Index = currentIndex;
				currentStack[currentStackSize] = value;
				mBinList[j-1].StackSize = currentStackSize+1;
				mBinList[j-1].Stack = currentStack;
				
			} 
		}
		else
		{
			if (i == 0)
				mBinList[i].CurrentHeight = newValue;
			else
			{
				int j = i - 1;
				while (j > -1 && mBinList[j].CurrentHeight > newValue)
				{
					j--;
				}
				for (int k = i - 1; k > j; k--)
				{
					mBinList[k+1].CurrentHeight = mBinList[k].CurrentHeight;
					mBinList[k+1].Index = mBinList[k].Index;
					mBinList[k+1].StackSize = mBinList[k].StackSize;
					mBinList[k+1].Stack = mBinList[k].Stack;
				}
				mBinList[j+1].CurrentHeight = newValue;
				mBinList[j+1].Index = currentIndex;
				currentStack[currentStackSize-1] = 0;
				mBinList[j+1].StackSize = currentStackSize-1;
				mBinList[j+1].Stack = currentStack;

			}
		}
		return true;

	}
	else
		return false;
}

void CBinList::SetBinForUnfilledStrip(CStripList &stripList, int indexUnfilledStrip)
{
	CStrip strip = stripList.GetValueUnfilled(indexUnfilledStrip);
	float stripHeight = strip.GetHeight();
	float currentLongestFinishTime = mBinList[mSize - 1].CurrentHeight;
	int j;
	for (j = mSize - 2; j >0; j--)
		if (currentLongestFinishTime - mBinList[j].CurrentHeight > stripHeight)
			break;
	stripList.SetBinValueForUnfilledElm(indexUnfilledStrip, mBinList[j].Index);
	AddHeight(j, stripHeight);
}

int CBinList::FindPositionOfBinIndex(int binIndex)
{
	int j = -1;
	for (j = 0; j < mSize; j++)
		if (mBinList[j].Index == binIndex)
			break;
	return j;
}